package com.java.design;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * 单例模式
 * 
 * @author Administrator
 *
 */

class Singleton {
	// 唯一的单例
	private static Singleton singleton = null;

	// 私有构造器
	private Singleton() {
		System.out.println(Thread.currentThread() + "：创建Singleton对象");
	}

	// 静态方法创建实例:不满足线程安全
	public static Singleton getInstance1() {
		if (singleton == null) {
			singleton = new Singleton();
		}
		return singleton;
	}

	// 静态方法创建实例:满足线程安全，但是性能低
	public static synchronized Singleton getInstance2() {
		if (singleton == null) {
			singleton = new Singleton();
		}
		return singleton;
	}

	// 静态方法创建实例:满足线程安全，满足性能要求，但是可能基于JVM优化策略，内存会延迟分配
	public static Singleton getInstance3() {
		if (singleton == null) {
			// singleton：这里未初始化会抛出异常
			synchronized (singleton) {
				if (singleton == null) {
					// 这里可能并不会第一个时间内分配到内存
					singleton = new Singleton();
				}
			}
		}
		return singleton;
	}

	// 静态类方式：利用类在加载时线程互相排斥的属性进行唯一初始化对象
	private static class SingletonFactory {
		private static Singleton singleton = new Singleton();
	}

	// 利用静态类方式
	public static Singleton getInstance4() {
		return SingletonFactory.singleton;
	}
}

//创建多线程
class SingletonCreate implements Runnable {
	public void run() {
		// 执行方法1创建对象
		Singleton.getInstance4();
	}
}

public class SingletonMode {
	public static void main(String[] args) {
		// 多线程测试
		ExecutorService exec = Executors.newCachedThreadPool();
		for (int i = 0; i < 10; i++) {
			exec.execute(new SingletonCreate());
		}
		try {
			TimeUnit.SECONDS.sleep(1);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		exec.shutdown();
	}
}

/**
 * getInstance1 执行结果： Thread[pool-1-thread-5,5,main]：创建Singleton对象
 * Thread[pool-1-thread-6,5,main]：创建Singleton对象
 * Thread[pool-1-thread-1,5,main]：创建Singleton对象
 * Thread[pool-1-thread-2,5,main]：创建Singleton对象
 * Thread[pool-1-thread-4,5,main]：创建Singleton对象
 * Thread[pool-1-thread-3,5,main]：创建Singleton对象
 * Thread[pool-1-thread-7,5,main]：创建Singleton对象
 * 
 * getInstance2：执行结果： Thread[pool-1-thread-5,5,main]：创建Singleton对象
 * 
 * getInstance3：Exception in thread "pool-1-thread-1" Exception in thread
 * "pool-1-thread-8" Exception in thread "pool-1-thread-9" Exception in thread
 * "pool-1-thread-2" java.lang.NullPointerException at
 * com.yxj.Singleton.getInstance3(SingletonMode.java:42)
 * 
 * getInstance3 执行结果： Thread[pool-1-thread-3,5,main]：创建Singleton对象
 */
